package tunnel

import (
	"bufio"
	"context"
	"crypto/tls"
	"encoding/binary"
	"fmt"
	"io"
	"log"
	"net"
	"strings"
	"sync"
	"time"

	"internal-net-bridge-server/internal/billing"     // 🆕 计费系统
	"internal-net-bridge-server/internal/tunnel/core" // 🔥 核心接口

	"github.com/quic-go/quic-go"
)

// QUICTunnelServer QUIC 隧道服务器
type QUICTunnelServer struct {
	addr          string
	tlsConfig     *tls.Config
	quicConfig    *quic.Config
	listener      *quic.Listener
	tunnelManager *TunnelManager
	ctx           context.Context
	cancel        context.CancelFunc
	wg            sync.WaitGroup

	// 🚀 连接池管理（tunnelID -> 连接池）
	connectionPools map[string]*QUICConnectionPool
	poolsMutex      sync.RWMutex

	// 管理QUIC连接（tunnelID -> QUIC连接）- 兼容旧版
	connections map[string]*quic.Conn
	connMutex   sync.RWMutex

	// 💰 计费管理器（可插拔式）
	billingManager *billing.BillingManager
}

// NewQUICTunnelServer 创建 QUIC 隧道服务器
func NewQUICTunnelServer(addr string, tlsConfig *tls.Config, tunnelManager *TunnelManager) (*QUICTunnelServer, error) {
	ctx, cancel := context.WithCancel(context.Background())

	// 🔥 QUIC 配置（高性能优化，参考TCP BBR + NPS的思想）
	// 🚀 极限优化：调整流控窗口以平衡性能和资源使用
	quicConfig := &quic.Config{
		MaxIncomingStreams:             10000,              // 最大并发 Stream
		MaxIncomingUniStreams:          0,                  // 禁用单向 Stream
		KeepAlivePeriod:                15 * time.Second,   // 🔥 缩短到15秒，更频繁保活（与客户端一致）
		MaxIdleTimeout:                 30 * time.Minute,   // 🔥 延长到30分钟（与客户端一致，防止僵尸连接）
		EnableDatagrams:                false,              // 禁用 Datagram（只用 Stream）
		InitialStreamReceiveWindow:     50 * 1024 * 1024,   // 🚀 调整到50MB（平衡性能和内存）
		MaxStreamReceiveWindow:         200 * 1024 * 1024,  // 🚀 调整到200MB
		InitialConnectionReceiveWindow: 200 * 1024 * 1024,  // 🚀 调整到200MB
		MaxConnectionReceiveWindow:     1024 * 1024 * 1024, // 🚀 调整到1GB
	}

	// 💰 创建计费管理器（默认禁用）
	billingManager := billing.NewBillingManager()
	// 💡 如需启用计费，在main.go中调用: quicServer.billingManager.Enable()

	server := &QUICTunnelServer{
		addr:            addr,
		tlsConfig:       tlsConfig,
		quicConfig:      quicConfig,
		tunnelManager:   tunnelManager,
		ctx:             ctx,
		cancel:          cancel,
		connections:     make(map[string]*quic.Conn),
		connectionPools: make(map[string]*QUICConnectionPool), // 🚀 初始化连接池
		billingManager:  billingManager,                       // 💰 计费管理器
	}

	// 🔥 初始化协议工厂（抽象接口架构）
	tunnelManager.protocolFactory = NewProtocolFactory(server)
	log.Printf("✅ [QUIC服务器] 协议工厂已初始化")

	return server, nil
}

// Start 启动 QUIC 隧道服务器
func (s *QUICTunnelServer) Start() error {
	// 创建 UDP 监听器
	udpAddr, err := net.ResolveUDPAddr("udp", s.addr)
	if err != nil {
		return fmt.Errorf("解析UDP地址失败: %v", err)
	}

	udpConn, err := net.ListenUDP("udp", udpAddr)
	if err != nil {
		return fmt.Errorf("监听UDP失败: %v", err)
	}

	// 创建 QUIC 监听器
	listener, err := quic.Listen(udpConn, s.tlsConfig, s.quicConfig)
	if err != nil {
		udpConn.Close()
		return fmt.Errorf("创建QUIC监听器失败: %v", err)
	}

	s.listener = listener

	log.Printf("🚀 [QUIC] 隧道服务器启动成功:")
	log.Printf("   ├─ 监听地址: %s", s.addr)
	log.Printf("   ├─ 协议: QUIC (UDP)")
	log.Printf("   ├─ TLS: 1.3 (ALPN: h3-tunnel)")
	log.Printf("   ├─ 最大并发Stream: %d", s.quicConfig.MaxIncomingStreams)
	log.Printf("   ├─ 保活间隔: %v", s.quicConfig.KeepAlivePeriod)
	log.Printf("   └─ 空闲超时: %v", s.quicConfig.MaxIdleTimeout)

	// 接受连接
	for {
		conn, err := s.listener.Accept(s.ctx)
		if err != nil {
			select {
			case <-s.ctx.Done():
				return nil // 服务器关闭
			default:
				log.Printf("⚠️ [QUIC] 接受连接失败: %v", err)
				continue
			}
		}

		// 为每个连接启动处理器
		s.wg.Add(1)
		go func() {
			defer s.wg.Done()
			s.handleConnection(conn)
		}()
	}
}

// Stop 停止 QUIC 隧道服务器
func (s *QUICTunnelServer) Stop() error {
	log.Printf("🛑 [QUIC] 停止隧道服务器...")

	s.cancel()

	if s.listener != nil {
		s.listener.Close()
	}

	// 等待所有连接处理完成
	s.wg.Wait()

	log.Printf("✅ [QUIC] 隧道服务器已停止")
	return nil
}

// handleConnection 处理单个 QUIC 连接
func (s *QUICTunnelServer) handleConnection(conn *quic.Conn) {
	remoteAddr := conn.RemoteAddr()
	log.Printf("📡 [QUIC] 新连接: %s", remoteAddr)

	var tunnelID string

	defer func() {
		// 清理连接映射
		if tunnelID != "" {
			s.connMutex.Lock()
			delete(s.connections, tunnelID)
			s.connMutex.Unlock()
			log.Printf("🗑️ [QUIC] 移除连接映射: tunnelID=%s", tunnelID[:8]+"...")
		}
		conn.CloseWithError(0, "connection closed")
		log.Printf("🔌 [QUIC] 连接断开: %s", remoteAddr)
	}()

	// 🔐 等待客户端发送第一个认证Stream
	// 客户端连接后会立即发送一个包含tunnelID的认证消息
	stream, err := conn.AcceptStream(s.ctx)
	if err != nil {
		log.Printf("❌ [QUIC] 接受认证Stream失败: %v", err)
		return
	}

	// 读取认证消息
	msg, err := ReadMessage(stream)
	if err != nil {
		log.Printf("❌ [QUIC] 读取认证消息失败: %v", err)
		stream.Close()
		return
	}

	tunnelID = msg.TunnelID
	if tunnelID == "" {
		log.Printf("❌ [QUIC] 认证消息缺少tunnelID")
		errorMsg := NewErrorMessage("", "", 1, "缺少tunnelID")
		errorMsg.Write(stream)
		stream.Close()
		return
	}

	// 验证隧道是否存在
	s.tunnelManager.mutex.RLock()
	tunnel, exists := s.tunnelManager.tunnels[tunnelID]
	s.tunnelManager.mutex.RUnlock()

	if !exists {
		log.Printf("❌ [QUIC] 隧道不存在: %s", tunnelID)
		errorMsg := NewErrorMessage(tunnelID, "", 2, "隧道不存在")
		errorMsg.Write(stream)
		stream.Close()
		return
	}

	// 🚀 新逻辑：使用连接池管理多个连接
	connID := msg.ConnectionID
	protocolType := msg.ProtocolType

	// 获取或创建连接池
	s.poolsMutex.Lock()
	pool, poolExists := s.connectionPools[tunnelID]
	if !poolExists {
		pool = NewQUICConnectionPool(tunnelID)
		s.connectionPools[tunnelID] = pool
		log.Printf("🎱 [连接池] 创建新连接池: TunnelID=%s", tunnelID[:8]+"...")
	}
	s.poolsMutex.Unlock()

	// 🔥🔥🔥 关键优化：客户端重启时快速清理已标记为不健康的旧连接
	// 策略：不主动验证新连接，只清理已经被标记为不健康的旧连接
	// 这样可以快速清理僵尸连接，而不会误杀新连接
	currentSize := pool.GetSize()
	if currentSize >= 12 {
		log.Printf("⚠️  [连接池] 检测到连接数较多(%d个)，触发快速清理...", currentSize)

		// 快速清理：只移除已标记为不健康的连接（不做主动验证）
		go func() {
			// 只需要稍微延迟一下，让新连接先加入池中
			time.Sleep(100 * time.Millisecond)

			// 🔥 执行快速清理（只清理已标记为不健康的连接）
			removed := pool.CleanupUnhealthyConnections()
			if removed > 0 {
				log.Printf("✅ [快速清理] 移除了%d个不健康连接，剩余%d个连接",
					removed, pool.GetSize())
			} else {
				log.Printf("ℹ️  [快速清理] 暂无需要清理的连接（连接数=%d）", pool.GetSize())
			}
		}()
	}

	// 添加连接到池中
	pool.AddConnection(conn, connID, protocolType)

	// 🔄 兼容旧逻辑：也保存到单连接map（用于第一次连接检测）
	s.connMutex.Lock()
	if _, exists := s.connections[tunnelID]; !exists {
		s.connections[tunnelID] = conn // 只在首次连接时保存
	}
	s.connMutex.Unlock()

	// 发送认证成功响应
	authOK := NewResponseMessage(tunnelID, "", []byte("AUTH_OK"))
	authOK.Write(stream)
	stream.Close()

	log.Printf("✅ [QUIC] 客户端认证成功:")
	log.Printf("   ├─ TunnelID: %s", tunnelID[:8]+"...")
	log.Printf("   ├─ ConnID: %s", connID[:8]+"...")
	log.Printf("   ├─ 协议: %s", protocolType)
	log.Printf("   ├─ 客户端: %s", remoteAddr)
	log.Printf("   └─ 目标: localhost:%d", tunnel.LocalPort)

	// 🚀 现在服务端可以主动推送请求到这个连接了
	// 保持连接打开，直到客户端断开或服务器关闭

	// 🔥 启动定期清理任务（每5分钟清理一次不健康连接）
	cleanupTicker := time.NewTicker(5 * time.Minute)
	defer cleanupTicker.Stop()

	go func() {
		for {
			select {
			case <-cleanupTicker.C:
				// 定期清理不健康连接
				removed := pool.CleanupUnhealthyConnections()
				if removed > 0 {
					log.Printf("🧹 [定期清理] TunnelID=%s, 移除了%d个僵尸连接, 剩余%d个健康连接",
						tunnelID[:8]+"...", removed, pool.GetSize())
				}

			case <-s.ctx.Done():
				return
			case <-conn.Context().Done():
				return
			}
		}
	}()

	select {
	case <-s.ctx.Done():
		log.Printf("🛑 [QUIC] 服务器关闭，断开连接: tunnelID=%s", tunnelID[:8]+"...")
	case <-conn.Context().Done():
		log.Printf("🔌 [QUIC] 客户端断开连接: tunnelID=%s, ConnID=%s", tunnelID[:8]+"...", connID[:8]+"...")

		// 🔥🔥🔥 关键优化：连接断开时自动清理所有僵尸连接
		s.poolsMutex.Lock()
		if pool, exists := s.connectionPools[tunnelID]; exists {
			// 1. 先移除断开的连接
			pool.RemoveConnection(connID, protocolType)
			currentSize := pool.GetSize()
			log.Printf("✅ [连接池] 已移除断开的连接: ConnID=%s, 剩余连接数=%d",
				connID[:8]+"...", currentSize)

			// 2. 检查连接池是否已空
			if currentSize == 0 {
				// 🚀🚀🚀 性能优化：连接数为0时，立即删除整个连接池
				// 原因：避免空连接池占用内存，防止下次新客户端复用旧的空池
				delete(s.connectionPools, tunnelID)
				log.Printf("🗑️  [连接池] 已删除空连接池: TunnelID=%s, 原因=所有连接已断开", tunnelID[:8]+"...")
			} else {
				// 3. 还有其他连接，触发僵尸连接清理
				log.Printf("🧹 [自动清理] 检测到连接断开，触发僵尸连接清理（当前连接数=%d）...", currentSize)

				// 4. 异步快速清理所有已标记为不健康的连接
				go func(p *QUICConnectionPool, tid string) {
					// 只需要很短的延迟，让其他可能断开的连接也能被移除
					time.Sleep(50 * time.Millisecond)

					removed := p.CleanupUnhealthyConnections()
					if removed > 0 {
						log.Printf("✅ [自动清理] 清理了%d个僵尸连接，剩余%d个健康连接",
							removed, p.GetSize())
					} else {
						log.Printf("ℹ️  [自动清理] 无需清理，所有连接健康（连接数=%d）", p.GetSize())
					}

					// 5. 清理后再次检查，如果清理后连接数为0，删除连接池
					finalSize := p.GetSize()
					if finalSize == 0 {
						s.poolsMutex.Lock()
						// 再次检查连接池是否还存在且为空（避免并发问题）
						if pool, exists := s.connectionPools[tid]; exists && pool.GetSize() == 0 {
							delete(s.connectionPools, tid)
							log.Printf("🗑️  [连接池] 清理后删除空连接池: TunnelID=%s", tid[:8]+"...")
						}
						s.poolsMutex.Unlock()
					}
				}(pool, tunnelID)
			}
		}
		s.poolsMutex.Unlock()
	}
}

// SendRequestToClient 通过 QUIC Stream 推送 HTTP 请求到客户端，并等待响应
// 这是服务端主动推送请求的关键方法
func (s *QUICTunnelServer) SendRequestToClient(tunnelID, requestID string, httpReq []byte, responseWriter net.Conn) error {
	// 🔥 获取隧道信息（用于协议类型和计费）
	s.tunnelManager.mutex.RLock()
	tunnel, tunnelExists := s.tunnelManager.tunnels[tunnelID]
	s.tunnelManager.mutex.RUnlock()

	if !tunnelExists {
		return fmt.Errorf("隧道不存在: tunnelID=%s", tunnelID)
	}

	// 🔥 解析协议类型（从tunnel.ProtocolType字符串转为ProtocolType枚举）
	var protocolType ProtocolType
	switch tunnel.ProtocolType {
	case "http", "HTTP":
		protocolType = ProtocolHTTP
	case "tcp", "TCP":
		protocolType = ProtocolTCP
	case "ssh", "SSH":
		protocolType = ProtocolSSH
	default:
		protocolType = ProtocolHTTP // 默认HTTP
	}

	// ========================================
	// 💰 计费系统检查（可插拔式集成）
	// 💡 如需禁用计费，注释掉下面整个if块即可
	// ========================================
	if s.billingManager != nil && s.billingManager.IsEnabled() {
		// 🔍 调试：打印UserID信息
		log.Printf("🔍 [计费] 隧道UserID: %s, TunnelID: %s", tunnel.UserID, tunnelID[:8]+"...")

		// 解析HTTP请求信息（可选，用于更精确的判断）
		httpMethod, httpPath, httpHeaders := parseHTTPRequestInfo(httpReq)

		// 构建拦截上下文
		billingCtx := &billing.InterceptContext{
			Ctx:           context.Background(),
			TunnelID:      tunnelID,
			UserID:        tunnel.UserID, // 🔑 从Tunnel获取UserID
			RequestID:     requestID,
			Protocol:      "HTTP",
			RemoteAddr:    responseWriter.RemoteAddr().String(),
			RequestSize:   int64(len(httpReq)),
			HTTPMethod:    httpMethod,
			HTTPPath:      httpPath,
			HTTPHeaders:   billing.ParseHTTPHeaders(httpHeaders),
			IsJSONRequest: billing.IsJSONRequest(billing.ParseHTTPHeaders(httpHeaders)),
			AcceptHTML:    billing.AcceptHTML(billing.ParseHTTPHeaders(httpHeaders)),
		}

		// 执行计费检查
		allowed, paymentResponse, err := s.billingManager.CheckRequest(billingCtx)
		if err != nil {
			log.Printf("❌ [计费] 检查失败: %v, RequestID=%s", err, requestID[:8]+"...")
			// 计费系统错误时继续处理请求（容错策略）
		} else if !allowed {
			// 🚫 请求被拦截，返回付费页面
			log.Printf("🚫 [计费] 请求被拦截: UserID=%s, TunnelID=%s, RequestID=%s",
				tunnel.UserID, tunnelID[:8]+"...", requestID[:8]+"...")

			// 发送付费响应（已包含HTTP头部）
			_, writeErr := responseWriter.Write(paymentResponse)
			if writeErr != nil {
				log.Printf("⚠️  [计费] 发送付费响应失败: %v", writeErr)
			}
			responseWriter.Close()
			return nil // 正常返回，不报错
		}

		// ✅ 计费检查通过，继续处理请求
		log.Printf("✅ [计费] 请求放行: UserID=%s, TunnelID=%s", tunnel.UserID, tunnelID[:8]+"...")
	}
	// ========================================
	// 计费检查结束
	// ========================================

	// 🚀 新逻辑：从连接池获取最空闲的连接
	s.poolsMutex.RLock()
	pool, poolExists := s.connectionPools[tunnelID]
	s.poolsMutex.RUnlock()

	if !poolExists {
		return fmt.Errorf("连接池不存在: tunnelID=%s", tunnelID)
	}

	// 🔥🔥🔥 关键优化：每次请求前先进行快速健康检查并清理僵尸连接
	// 这样可以确保轮询策略只在健康连接中选择，避免浪费时间在僵尸连接上
	// 注意：只对连接池中标记为不健康的连接进行清理，对健康连接不做额外检查
	currentPoolSize := pool.GetSize()
	if currentPoolSize > 0 {
		// 执行快速清理（不阻塞，只清理已标记为不健康的连接）
		removed := pool.CleanupUnhealthyConnections()
		if removed > 0 {
			log.Printf("🧹 [快速清理] 请求前清理了%d个僵尸连接（请求: %s）, 剩余%d个连接",
				removed, requestID[:8]+"...", pool.GetSize())
		}
	}

	// 🔥 自动重试：最多尝试3次获取健康连接
	var pooledConn *QUICPooledConnection
	var conn *quic.Conn
	var stream *quic.Stream
	var err error
	maxRetries := 3
	unhealthyCount := 0 // 🔥 统计遇到的不健康连接数

	for attempt := 1; attempt <= maxRetries; attempt++ {
		// 获取最空闲的HTTP协议连接
		pooledConn, err = pool.GetConnection(ProtocolHTTP)
		if err != nil {
			if attempt >= maxRetries {
				// 🔥 最后一次失败时，检查是否需要立即清理（降低阈值到3个）
				if unhealthyCount >= 3 {
					log.Printf("⚠️  [QUIC] 检测到不健康连接(%d个)，立即触发清理和重建...", unhealthyCount)
					removed := pool.CleanupUnhealthyConnections()
					log.Printf("✅ [立即清理] TunnelID=%s, 移除了%d个僵尸连接, 剩余%d个健康连接",
						tunnelID[:8]+"...", removed, pool.GetSize())

					// 🔥 如果剩余连接太少，触发客户端重连
					if pool.GetSize() < 4 {
						log.Printf("⚠️  [QUIC] 健康连接不足(%d个)，建议客户端重新建立连接池", pool.GetSize())
					}
				}
				return fmt.Errorf("获取连接失败: %v", err)
			}
			log.Printf("⚠️  [QUIC] 获取连接失败，重试: %d/%d", attempt, maxRetries)
			time.Sleep(100 * time.Millisecond)
			continue
		}

		conn = pooledConn.Conn

		// 🔥 关键修复：添加500ms超时，快速检测僵尸连接（极速响应优化）
		streamCtx, streamCancel := context.WithTimeout(s.ctx, 500*time.Millisecond)

		// 🔥 性能监控：记录OpenStreamSync耗时
		openStart := time.Now()
		stream, err = conn.OpenStreamSync(streamCtx)
		openDuration := time.Since(openStart)
		streamCancel() // 立即取消，不再需要

		// 警告：如果OpenStreamSync耗时超过200ms（极速响应要求）
		if openDuration > 200*time.Millisecond {
			log.Printf("⚠️  [QUIC] OpenStreamSync耗时较长: %.2fs, ConnID=%s, RequestID=%s",
				openDuration.Seconds(), pooledConn.ConnectionID[:8]+"...", requestID[:8]+"...")
		}

		if err == nil {
			// ✅ 成功打开Stream - 记录成功状态
			pooledConn.RecordStreamOpenSuccess()
			if attempt > 1 {
				log.Printf("✅ [QUIC] 重试成功: 尝试=%d/%d, ConnID=%s, RequestID=%s",
					attempt, maxRetries, pooledConn.ConnectionID[:8]+"...", requestID[:8]+"...")
			}
			break
		}

		// ❌ 打开Stream失败 - 记录失败状态
		log.Printf("⚠️  [QUIC] 打开Stream失败（僵尸连接）: ConnID=%s, Error=%v, 尝试=%d/%d",
			pooledConn.ConnectionID[:8]+"...", err, attempt, maxRetries)
		pooledConn.RecordStreamOpenFailure() // 🔥 记录失败，自动增加失败计数
		pooledConn.MarkUnhealthy()           // 标记此连接不健康
		unhealthyCount++                     // 🔥 增加不健康连接计数

		if attempt >= maxRetries {
			// 🔥 最后一次重试失败，立即清理此不健康连接
			if unhealthyCount >= 2 {
				log.Printf("⚠️  [QUIC] 多次打开Stream失败(%d次)，立即清理不健康连接...", unhealthyCount)
				removed := pool.CleanupUnhealthyConnections()
				if removed > 0 {
					log.Printf("✅ [立即清理] 移除了%d个僵尸连接", removed)
				}
			}
			return fmt.Errorf("打开Stream失败（所有重试都失败）: %v", err)
		}

		// 🔥 极速响应：缩短延迟到10ms
		time.Sleep(10 * time.Millisecond)
	}

	// 🚀 极限优化：使用512KB缓冲区加速浏览器写入，避免TCP阻塞QUIC读取
	bufferedWriter := bufio.NewWriterSize(responseWriter, 512*1024) // 512KB缓冲区
	defer func() {
		if bufferedWriter != nil {
			bufferedWriter.Flush() // 确保所有数据刷出
		}
	}()

	// 🚀 增加连接的活跃Stream计数
	pooledConn.IncrementStreams()
	defer func() {
		pooledConn.DecrementStreams() // 🚀 减少计数
		if stream != nil {
			stream.Close()
		}
	}()

	log.Printf("📤 [QUIC] 推送请求到客户端: StreamID=%d, TunnelID=%s, ConnID=%s, RequestID=%s, Protocol=%s, Size=%d bytes",
		stream.StreamID(), tunnelID[:8]+"...", pooledConn.ConnectionID[:8]+"...", requestID[:8]+"...", protocolType, len(httpReq))

	// 🔥 构建请求消息（带协议类型）
	requestMsg := NewRequestMessage(tunnelID, requestID, httpReq, protocolType)

	// 🔥 性能监控：记录WriteMessage耗时
	writeStart := time.Now()
	if err := requestMsg.Write(stream); err != nil {
		return fmt.Errorf("发送请求失败: %v", err)
	}
	writeDuration := time.Since(writeStart)

	// 🔥🔥🔥 记录到连接池统计（用于智能选择）
	pooledConn.RecordWriteDuration(writeDuration)

	// 警告：如果WriteMessage耗时超过50ms
	if writeDuration > 50*time.Millisecond {
		log.Printf("⚠️  [QUIC] WriteMessage耗时较长: %.2fs, Size=%d bytes, ConnID=%s, RequestID=%s",
			writeDuration.Seconds(), len(httpReq), pooledConn.ConnectionID[:8]+"...", requestID[:8]+"...")
	}

	log.Printf("⏳ [QUIC] 等待客户端响应: RequestID=%s", requestID[:8]+"...")

	// 🚀🚀🚀 HTTP/2混合模式：注册等待响应（HTTP/2优先，QUIC降级）
	// 🔥 传递responseWriter(浏览器连接)，HTTP/2处理器会直接写入响应
	// ⚠️  不使用defer注销，在接收到响应后手动注销（避免在大文件传输时提前注销）
	// 🎯 2025-11-11优化：超时从300秒 → 420秒（7分钟），支持GB级大文件分片拉取
	http2PendingResp := s.tunnelManager.http2Handler.RegisterPendingResponse(requestID, responseWriter, 420*time.Second)

	// 🔥🔥🔥 修复死锁 + 超时保护：使用goroutine读取 + 超时控制
	type readResult struct {
		firstByte []byte
		err       error
	}
	readChan := make(chan readResult, 1)
	browserClosedChan := make(chan struct{}, 1)
	streamClosedChan := make(chan struct{}, 1)

	// Goroutine 1: 读取客户端响应
	go func() {
		defer func() {
			// 🎯 2025-11-06优化：确保goroutine正常退出
			if r := recover(); r != nil {
				log.Printf("⚠️  [QUIC] 读取响应goroutine panic: %v, RequestID=%s", r, requestID[:8]+"...")
				readChan <- readResult{firstByte: nil, err: fmt.Errorf("panic: %v", r)}
			}
		}()

		firstByte := make([]byte, 1)
		_, err := io.ReadFull(stream, firstByte)
		select {
		case readChan <- readResult{firstByte: firstByte, err: err}:
			// 成功发送
		case <-time.After(1 * time.Second):
			// 避免goroutine泄漏：如果1秒内无法发送，放弃
			log.Printf("⚠️  [QUIC] 读取响应通道阻塞，goroutine退出: RequestID=%s", requestID[:8]+"...")
		}
	}()

	// Goroutine 2: 监听浏览器断开
	// 🔥🔥🔥 关键修复：判断请求方法，只对下载场景监听浏览器断开
	// 问题：对于POST上传请求，浏览器正在发送Body，responseWriter.Read()会立即失败导致误判
	// 解决：检查HTTP请求方法，只对GET/HEAD等下载场景启用浏览器断开检测
	go func() {
		defer func() {
			// 🎯 2025-11-06优化：确保goroutine正常退出
			if r := recover(); r != nil {
				log.Printf("⚠️  [QUIC] 浏览器断开检测goroutine panic: %v, RequestID=%s", r, requestID[:8]+"...")
			}
		}()

		// 解析HTTP请求方法
		httpMethod := "GET" // 默认GET
		if len(httpReq) > 4 {
			firstLine := string(httpReq[:min(len(httpReq), 100)])
			if idx := strings.Index(firstLine, " "); idx > 0 {
				httpMethod = firstLine[:idx]
			}
		}

		// 只对下载场景(GET/HEAD)启用浏览器断开检测
		// 上传场景(POST/PUT)不需要检测，因为浏览器会等待响应
		if httpMethod == "GET" || httpMethod == "HEAD" {
			buf := make([]byte, 1)
			_, err := responseWriter.Read(buf)
			if err != nil {
				select {
				case <-browserClosedChan:
					// 已关闭，不重复关闭
				default:
					close(browserClosedChan)
					if stream != nil {
						stream.Close() // 立即关闭stream通知客户端
					}
				}
			}
		}
	}()

	// Goroutine 3: 监听stream关闭（客户端主动关闭）
	go func() {
		defer func() {
			// 🎯 2025-11-06优化：确保goroutine正常退出
			if r := recover(); r != nil {
				log.Printf("⚠️  [QUIC] Stream关闭监听goroutine panic: %v, RequestID=%s", r, requestID[:8]+"...")
			}
		}()

		// 等待stream上下文完成，表示stream已关闭
		<-stream.Context().Done()
		select {
		case <-streamClosedChan:
			// 已关闭，不重复关闭
		default:
			close(streamClosedChan)
		}
	}()

	// 🚀🚀🚀 优化：等待客户端响应（HTTP/2优先，自动降级到QUIC）
	var firstByte []byte
	select {
	// 🔥🔥🔥 等待HTTP/2响应完成信号（响应已在HTTP/2处理器中直接写给浏览器）
	case <-http2PendingResp.ResponseChan:
		// 🔥 手动注销响应通道
		s.tunnelManager.http2Handler.UnregisterPendingResponse(requestID)

		log.Printf("✅ [HTTP/2混合] HTTP/2响应已完成: RequestID=%s", requestID[:8]+"...")
		return nil

	case http2Err := <-http2PendingResp.ErrorChan:
		// 🔥 手动注销响应通道（HTTP/2失败）
		s.tunnelManager.http2Handler.UnregisterPendingResponse(requestID)

		// HTTP/2发生错误，降级到QUIC
		log.Printf("⚠️  [HTTP/2混合] HTTP/2错误，降级到QUIC: %v, RequestID=%s", http2Err, requestID[:8]+"...")
		// 继续等待QUIC响应（fallthrough到下面的readChan处理）
		select {
		case result := <-readChan:
			if result.err != nil {
				select {
				case <-browserClosedChan:
					return nil
				case <-streamClosedChan:
					return nil
				default:
					if strings.Contains(result.err.Error(), "timeout") ||
						strings.Contains(result.err.Error(), "connection") ||
						strings.Contains(result.err.Error(), "closed") {
						log.Printf("🌐 [QUIC] 网络连接问题: %v, RequestID=%s", result.err, requestID[:8]+"...")
						return nil
					}
					return fmt.Errorf("读取消息类型失败: %v", result.err)
				}
			}
			firstByte = result.firstByte
			log.Printf("✅ [QUIC降级] 收到QUIC响应: RequestID=%s", requestID[:8]+"...")
		case <-time.After(5 * time.Second):
			log.Printf("⏱️  [QUIC降级] 等待QUIC响应超时: RequestID=%s", requestID[:8]+"...")
			return fmt.Errorf("等待响应超时")
		}

	case result := <-readChan:
		// 客户端响应到达
		if result.err != nil {
			// 🚀 优化：更精确的错误分类和处理
			select {
			case <-browserClosedChan:
				// 🔥 减少日志：快速拖动时会频繁触发
				return nil
			case <-streamClosedChan:
				// 🔥 减少日志：快速拖动时会频繁触发
				return nil
			default:
				// 检查是否是网络错误或超时
				if strings.Contains(result.err.Error(), "timeout") ||
					strings.Contains(result.err.Error(), "connection") ||
					strings.Contains(result.err.Error(), "closed") {
					log.Printf("🌐 [QUIC] 网络连接问题: %v, RequestID=%s", result.err, requestID[:8]+"...")
					return nil // 网络问题不返回错误，避免误报
				}
				return fmt.Errorf("读取消息类型失败: %v", result.err)
			}
		}
		firstByte = result.firstByte
		log.Printf("✅ [QUIC] 收到客户端响应: RequestID=%s", requestID[:8]+"...")

	case <-browserClosedChan:
		// 🔥 手动注销响应通道（浏览器关闭）
		s.tunnelManager.http2Handler.UnregisterPendingResponse(requestID)

		// 🚀 优化：浏览器断开检测更精确（快速拖动时会频繁触发，减少日志）
		// 🔥🔥🔥 关键修复：使用CancelWrite立即中断正在进行的写入操作
		// 原因：Close()不会立即中断Write，导致客户端继续发送数据导致流控阻塞
		// CancelWrite会立即终止Stream的写入端，客户端的Write会立即返回错误
		if stream != nil {
			stream.CancelWrite(0) // 取消写入端，错误码0表示正常取消
			stream.Close()        // 同时关闭读取端
		}
		return nil

	case <-streamClosedChan:
		// 🔥 手动注销响应通道（Stream关闭）
		s.tunnelManager.http2Handler.UnregisterPendingResponse(requestID)

		// 🚀 优化：客户端断开检测
		log.Printf("🚫 [QUIC] 客户端断开连接，取消请求: RequestID=%s", requestID[:8]+"...")
		return nil

	case <-time.After(300 * time.Second):
		// 🔥🔥🔥 关键修复：超时后给HTTP/2响应一个宽限期（120秒）
		// 问题：大文件传输时，HTTP/2响应可能在超时边缘到达，立即注销会导致404
		// 解决：延长基础超时到300秒（5分钟），并在超时后等待120秒（2分钟）再注销
		// 🎯 2025-11-11优化：支持GB级大文件分片拉取，客户端需要时间并发拉取分片
		log.Printf("⏱️  [QUIC] 等待响应超时（300秒），给HTTP/2一个宽限期（120秒）: RequestID=%s", requestID[:8]+"...")

		// 🔥 在宽限期内继续等待HTTP/2响应完成
		select {
		case <-http2PendingResp.ResponseChan:
			s.tunnelManager.http2Handler.UnregisterPendingResponse(requestID)
			log.Printf("✅ [HTTP/2宽限期] HTTP/2响应已完成: RequestID=%s", requestID[:8]+"...")
			return nil

		case http2Err := <-http2PendingResp.ErrorChan:
			s.tunnelManager.http2Handler.UnregisterPendingResponse(requestID)
			log.Printf("❌ [HTTP/2宽限期] HTTP/2错误: %v, RequestID=%s", http2Err, requestID[:8]+"...")
			return http2Err

		case <-time.After(120 * time.Second):
			// 宽限期结束，真正超时
			s.tunnelManager.http2Handler.UnregisterPendingResponse(requestID)
			log.Printf("❌ [QUIC] 真正超时（300+120秒），请求失败: RequestID=%s", requestID[:8]+"...")
			if stream != nil {
				stream.Close()
			}
			return fmt.Errorf("等待响应超时")
		}
	}

	// 根据第一个字节判断是流式响应还是标准响应
	if firstByte[0] == MessageTypeResponseChunk {
		// 🚀🚀🚀 流水线处理：接收和发送并行进行（高速公路模式）
		//
		// 架构说明：
		// ┌─────────┐    接收管道    ┌──────────┐    发送管道    ┌─────────┐
		// │ QUIC流  │ ──────────────> │ 缓冲队列 │ ──────────────> │ 浏览器  │
		// └─────────┘   (异步接收)   └──────────┘   (异步发送)   └─────────┘
		//                车站A                                      车站B
		//
		// 优势：
		// 1. 接收和发送解耦，互不阻塞
		// 2. 缓冲队列平滑数据流动
		// 3. 最大化利用网络管道

		log.Printf("📺 [QUIC] 检测到流式响应，启动流水线接收...")

		// 读取第一个分片的剩余部分（因为MessageType已经读取了）
		firstChunk, err := readFirstChunk(stream, firstByte[0], requestID)
		if err != nil {
			return fmt.Errorf("读取首个分片失败: %v", err)
		}

		// 定义分片数据结构
		type chunkData struct {
			data   []byte
			isLast bool
		}

		// 缓冲队列：5个分片的缓冲（平衡内存和性能）
		chunkQueue := make(chan chunkData, 5)
		receiveError := make(chan error, 1)
		sendError := make(chan error, 1)
		chunkCount := uint32(0)

		// 🚀 车站A：异步接收goroutine
		go func() {
			defer close(chunkQueue)

			// 先发送第一个分片到队列
			select {
			case chunkQueue <- chunkData{
				data:   firstChunk.ChunkData,
				isLast: firstChunk.IsLastChunk,
			}:
				chunkCount++
				if firstChunk.IsLastChunk {
					return // 只有一个分片
				}
			case <-browserClosedChan:
				return
			case <-streamClosedChan:
				return
			}

			// 继续接收后续分片
			for {
				// 检查是否断开
				select {
				case <-browserClosedChan:
					log.Printf("🚫 [QUIC] 浏览器断开，停止接收: RequestID=%s", requestID[:8]+"...")
					return
				case <-streamClosedChan:
					log.Printf("🚫 [QUIC] 客户端断开，停止接收: RequestID=%s", requestID[:8]+"...")
					return
				default:
				}

				// 读取分片
				chunk, err := ReadChunkMessage(stream)
				if err != nil {
					if err == io.EOF {
						log.Printf("✅ [QUIC] 接收完成（EOF）: RequestID=%s, 已接收%d个分片",
							requestID[:8]+"...", chunkCount)
						return
					}

					// 检查是否是stream关闭导致的错误
					select {
					case <-streamClosedChan:
						log.Printf("🚫 [QUIC] 客户端断开: RequestID=%s", requestID[:8]+"...")
						return
					default:
						receiveError <- fmt.Errorf("读取分片失败: %v", err)
						return
					}
				}

				// 验证RequestID
				if chunk.RequestID != requestID {
					receiveError <- fmt.Errorf("RequestID不匹配: 期望=%s, 实际=%s", requestID, chunk.RequestID)
					return
				}

				chunkCount++

				// 发送到队列
				select {
				case chunkQueue <- chunkData{
					data:   chunk.ChunkData,
					isLast: chunk.IsLastChunk,
				}:
					if chunk.IsLastChunk {
						log.Printf("✅ [QUIC] 接收完成: RequestID=%s, 总计%d个分片", requestID[:8]+"...", chunkCount)
						return
					}
				case <-browserClosedChan:
					return
				case <-streamClosedChan:
					return
				}
			}
		}()

		// 🚀 车站B：异步发送goroutine
		go func() {
			sentCount := uint32(0)
			sentBytes := int64(0)

			for {
				select {
				case chunkInfo, ok := <-chunkQueue:
					if !ok {
						// 队列关闭，接收完成
						return
					}

					// 写入分片数据到浏览器
					if _, err := bufferedWriter.Write(chunkInfo.data); err != nil {
						log.Printf("🚫 [QUIC] 浏览器断开，停止发送: RequestID=%s", requestID[:8]+"...")
						if stream != nil {
							stream.Close() // 通知客户端停止发送
						}
						sendError <- err
						return
					}

					sentCount++
					sentBytes += int64(len(chunkInfo.data))

					// 每10个分片打印进度
					if sentCount%10 == 0 {
						log.Printf("📤 [QUIC] 已发送 %d 个分片到浏览器: %.2f MB",
							sentCount, float64(sentBytes)/(1024*1024))
					}

					// 最后一个分片
					if chunkInfo.isLast {
						// 刷新缓冲区
						bufferedWriter.Flush()
						// 优雅关闭连接
						if tcpConn, ok := responseWriter.(interface{ CloseWrite() error }); ok {
							tcpConn.CloseWrite()
						}
						time.Sleep(10 * time.Millisecond)
						responseWriter.Close()
						log.Printf("✅ [QUIC] 发送完成: RequestID=%s, Chunks=%d, Size=%.2f MB",
							requestID[:8]+"...", sentCount, float64(sentBytes)/(1024*1024))
						return
					}

				case <-browserClosedChan:
					log.Printf("🚫 [QUIC] 浏览器断开，停止发送: RequestID=%s", requestID[:8]+"...")
					if stream != nil {
						stream.Close()
					}
					return
				}
			}
		}()

		// 等待接收或发送完成
		select {
		case err := <-receiveError:
			log.Printf("❌ [QUIC] 接收错误: %v (RequestID=%s)", err, requestID[:8]+"...")
			return err
		case err := <-sendError:
			log.Printf("❌ [QUIC] 发送错误: %v (RequestID=%s)", err, requestID[:8]+"...")
			return nil // 发送错误不返回错误（浏览器断开是正常的）
		case <-browserClosedChan:
			log.Printf("🚫 [QUIC] 浏览器断开: RequestID=%s", requestID[:8]+"...")
			if stream != nil {
				stream.Close()
			}
			return nil
		case <-streamClosedChan:
			log.Printf("🚫 [QUIC] 客户端断开: RequestID=%s", requestID[:8]+"...")
			return nil
		}

	} else if firstByte[0] == byte(ProtocolMagic>>24) {
		// 标准响应：期望读取完整的ResponseMessage
		log.Printf("📄 [QUIC] 检测到标准响应，读取完整消息...")

		// 读取剩余的Header（已经读取了第一个字节）
		remainingHeader := make([]byte, HeaderSize-1)
		if _, err := io.ReadFull(stream, remainingHeader); err != nil {
			// 检查是否是stream关闭导致的错误
			select {
			case <-streamClosedChan:
				log.Printf("🚫 [QUIC] 客户端断开，标准响应读取中断: RequestID=%s", requestID[:8]+"...")
				return nil
			default:
				return fmt.Errorf("读取Header失败: %v", err)
			}
		}

		// 组合完整的Header
		fullHeader := append(firstByte, remainingHeader...)

		// 解码Header
		msg, err := DecodeHeader(fullHeader)
		if err != nil {
			return fmt.Errorf("解码Header失败: %v", err)
		}

		// 读取Body
		if msg.BodyLength > 0 {
			msg.Body = make([]byte, msg.BodyLength)
			if _, err := io.ReadFull(stream, msg.Body); err != nil {
				// 检查是否是stream关闭导致的错误
				select {
				case <-streamClosedChan:
					log.Printf("🚫 [QUIC] 客户端断开，Body读取中断: RequestID=%s", requestID[:8]+"...")
					return nil
				default:
					return fmt.Errorf("读取Body失败: %v", err)
				}
			}
		}

		// 检查响应类型
		if msg.MessageType == MessageTypeError {
			errorCode := msg.Reserved
			errorMsg := string(msg.Body)
			return fmt.Errorf("客户端错误 (code=%d): %s", errorCode, errorMsg)
		}

		// 将响应写入浏览器连接
		if _, err := responseWriter.Write(msg.Body); err != nil {
			log.Printf("ℹ️  [QUIC] 浏览器连接已关闭: RequestID=%s", requestID[:8]+"...")
			return nil
		}

		// 🚀 NPS优化：优雅关闭连接，确保数据完全发送
		if tcpConn, ok := responseWriter.(interface{ CloseWrite() error }); ok {
			tcpConn.CloseWrite() // 半关闭，允许数据完全发送
		}
		time.Sleep(10 * time.Millisecond) // 等待数据发送完毕
		responseWriter.Close()
		log.Printf("✅ [QUIC] 标准响应完成: RequestID=%s, Size=%d bytes",
			requestID[:8]+"...", msg.BodyLength)

	} else {
		return fmt.Errorf("未知的消息类型: 0x%02X", firstByte[0])
	}

	return nil
}

// readFirstChunk 读取第一个分片（MessageType已经读取）
func readFirstChunk(r io.Reader, messageType uint8, expectedRequestID string) (*ChunkMessage, error) {
	chunk := &ChunkMessage{
		MessageType: messageType,
	}

	// 读取TunnelID（36字节）
	tunnelIDBytes := make([]byte, 36)
	if _, err := io.ReadFull(r, tunnelIDBytes); err != nil {
		return nil, fmt.Errorf("读取TunnelID失败: %v", err)
	}
	chunk.TunnelID = string(tunnelIDBytes)

	// 读取RequestID（36字节）
	requestIDBytes := make([]byte, 36)
	if _, err := io.ReadFull(r, requestIDBytes); err != nil {
		return nil, fmt.Errorf("读取RequestID失败: %v", err)
	}
	chunk.RequestID = string(requestIDBytes)

	// 读取分片索引
	if err := binary.Read(r, binary.BigEndian, &chunk.ChunkIndex); err != nil {
		return nil, fmt.Errorf("读取分片索引失败: %v", err)
	}

	// 读取是否最后一个分片
	var isLast uint8
	if err := binary.Read(r, binary.BigEndian, &isLast); err != nil {
		return nil, fmt.Errorf("读取IsLastChunk失败: %v", err)
	}
	chunk.IsLastChunk = isLast == 1

	// 读取分片长度
	if err := binary.Read(r, binary.BigEndian, &chunk.ChunkLength); err != nil {
		return nil, fmt.Errorf("读取分片长度失败: %v", err)
	}

	// 读取分片数据
	chunk.ChunkData = make([]byte, chunk.ChunkLength)
	if _, err := io.ReadFull(r, chunk.ChunkData); err != nil {
		return nil, fmt.Errorf("读取分片数据失败: %v", err)
	}

	return chunk, nil
}

// ========================================
// 💰 计费系统辅助函数
// ========================================

// parseHTTPRequestInfo 解析HTTP请求信息（用于计费系统）
func parseHTTPRequestInfo(httpReq []byte) (method, path string, headers map[string][]string) {
	// 默认值
	method = "GET"
	path = "/"
	headers = make(map[string][]string)

	// 解析HTTP请求行
	lines := strings.Split(string(httpReq), "\r\n")
	if len(lines) > 0 {
		// 解析请求行：GET /path HTTP/1.1
		parts := strings.Split(lines[0], " ")
		if len(parts) >= 2 {
			method = parts[0]
			path = parts[1]
		}
	}

	// 解析HTTP头部
	for i := 1; i < len(lines); i++ {
		line := lines[i]
		if line == "" {
			break // 头部结束
		}

		// 解析头部：Header-Name: Header-Value
		colonIdx := strings.Index(line, ":")
		if colonIdx > 0 {
			headerName := strings.TrimSpace(line[:colonIdx])
			headerValue := strings.TrimSpace(line[colonIdx+1:])
			headers[headerName] = append(headers[headerName], headerValue)
		}
	}

	return method, path, headers
}

// GetBillingManager 获取计费管理器（供外部配置使用）
func (s *QUICTunnelServer) GetBillingManager() *billing.BillingManager {
	return s.billingManager
}

// SetTunnelUserID 设置隧道的UserID（用于测试或管理）
// 💡 用于将现有隧道的UserID改为指定值
func (s *QUICTunnelServer) SetTunnelUserID(tunnelID, userID string) error {
	s.tunnelManager.mutex.Lock()
	defer s.tunnelManager.mutex.Unlock()

	tunnel, exists := s.tunnelManager.tunnels[tunnelID]
	if !exists {
		return fmt.Errorf("隧道不存在: %s", tunnelID)
	}

	oldUserID := tunnel.UserID
	tunnel.UserID = userID
	log.Printf("🔧 [计费] 更新隧道UserID: TunnelID=%s, %s → %s", tunnelID[:8]+"...", oldUserID, userID)
	return nil
}

// GetAllTunnels 获取所有隧道信息（用于查看UserID）
func (s *QUICTunnelServer) GetAllTunnels() map[string]string {
	s.tunnelManager.mutex.RLock()
	defer s.tunnelManager.mutex.RUnlock()

	result := make(map[string]string)
	for tunnelID, tunnel := range s.tunnelManager.tunnels {
		result[tunnelID] = tunnel.UserID
	}
	return result
}

// GetContext 获取上下文（供转发器使用）
func (s *QUICTunnelServer) GetContext() context.Context {
	return s.ctx
}

// GetQUICConnection 获取QUIC连接（供TCP转发器使用，简化接口）
func (s *QUICTunnelServer) GetQUICConnection(tunnelID string, protocolType core.ProtocolType) (*quic.Conn, error) {
	s.poolsMutex.Lock()
	pool, exists := s.connectionPools[tunnelID]
	s.poolsMutex.Unlock()

	if !exists {
		return nil, fmt.Errorf("连接池不存在: %s", tunnelID)
	}

	// 获取QUIC连接（类型转换）
	quicConn, err := pool.GetConnection(ProtocolType(protocolType))
	if err != nil {
		return nil, fmt.Errorf("获取QUIC连接失败: %w", err)
	}

	return quicConn.Conn, nil
}
